<template>
  <div class="dashboard-wrapper" v-loading="loading">
    <section v-if="!hideHeader" class="dashboard-header">
      <div class="header-info">
        <h1 class="title">项目仪表盘</h1>
        <p class="subtitle">纵览项目全局态势，捕捉关键趋势并聚焦团队效率。</p>
      </div>
      <div class="header-actions">
        <el-select
          v-model="filters.period"
          size="small"
          class="period-select"
          @change="handlePeriodChange"
        >
          <el-option label="按周聚合" value="week" />
          <el-option label="按月聚合" value="month" />
          <el-option label="按季度聚合" value="quarter" />
        </el-select>
        <el-radio-group
          v-model="quickRange"
          size="small"
          class="range-group"
          @change="handleQuickRangeChange"
        >
          <el-radio-button
            v-for="item in quickRangeOptions"
            :key="item.value"
            :label="item.value"
          >
            {{ item.label }}
          </el-radio-button>
        </el-radio-group>
        <el-date-picker
          v-model="filters.dateRange"
          type="daterange"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          format="YYYY-MM-DD"
          value-format="YYYY-MM-DD"
          :disabled="quickRange !== 'custom'"
          :unlink-panels="true"
          size="small"
          class="date-picker"
          @change="handleDateChange"
        />
        <el-select
          v-model="selectedProjectId"
          placeholder="搜索项目..."
          size="small"
          clearable
          filterable
          class="search-select"
          @change="handleProjectChange"
          style="width: 250px;"
        >
          <el-option
            label="全部项目"
            value=""
          />
          <el-option
            v-for="project in projectOptions"
            :key="project.id"
            :label="project.name"
            :value="project.id"
          />
        </el-select>
        <el-button type="primary" size="small" :loading="loading" @click="refreshAll">
          <el-icon><Refresh /></el-icon>
          刷新
        </el-button>
      </div>
    </section>
    
    <!-- 当隐藏头部时，显示筛选控件 -->
    <section v-if="hideHeader" class="dashboard-filters-bar">
      <div class="filters-actions">
        <el-select
          v-model="filters.period"
          size="small"
          class="period-select"
          @change="handlePeriodChange"
        >
          <el-option label="按周聚合" value="week" />
          <el-option label="按月聚合" value="month" />
          <el-option label="按季度聚合" value="quarter" />
        </el-select>
        <el-radio-group
          v-model="quickRange"
          size="small"
          class="range-group"
          @change="handleQuickRangeChange"
        >
          <el-radio-button
            v-for="item in quickRangeOptions"
            :key="item.value"
            :label="item.value"
          >
            {{ item.label }}
          </el-radio-button>
        </el-radio-group>
        <el-date-picker
          v-model="filters.dateRange"
          type="daterange"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          format="YYYY-MM-DD"
          value-format="YYYY-MM-DD"
          :disabled="quickRange !== 'custom'"
          :unlink-panels="true"
          size="small"
          class="date-picker"
          @change="handleDateChange"
        />
        <el-select
          v-model="selectedProjectId"
          placeholder="搜索项目..."
          size="small"
          clearable
          filterable
          class="search-select"
          @change="handleProjectChange"
          style="width: 250px;"
        >
          <el-option
            label="全部项目"
            value=""
          />
          <el-option
            v-for="project in projectOptions"
            :key="project.id"
            :label="project.name"
            :value="project.id"
          />
        </el-select>
        <el-button type="primary" size="small" :loading="loading" @click="refreshAll">
          <el-icon><Refresh /></el-icon>
          刷新
        </el-button>
      </div>
    </section>

    <section class="overview-section">
      <el-row :gutter="16">
        <el-col
          v-for="card in summaryCards"
          :key="card.key"
          :xs="12"
          :sm="12"
          :md="6"
        >
          <el-card class="stat-card" shadow="hover">
            <div class="stat-card__icon" :style="{ background: card.tint }">
              <el-icon :size="20" :style="{ color: card.color }">
                <component :is="card.icon" />
              </el-icon>
            </div>
            <div class="stat-card__content">
              <span class="stat-card__label">{{ card.title }}</span>
              <div class="stat-card__value">
                <span>{{ card.displayValue }}</span>
                <transition name="trend-fade">
                  <span
                    v-if="card.trend !== 0"
                    :class="['stat-card__trend', card.trend > 0 ? 'is-up' : 'is-down']"
                  >
                    <el-icon><TrendCharts /></el-icon>
                    {{ card.trend > 0 ? '+' : '' }}{{ card.trend }}
                  </span>
                </transition>
              </div>
              <p class="stat-card__meta">{{ card.subtitle }}</p>
            </div>
          </el-card>
        </el-col>
      </el-row>
    </section>

    <section class="chart-section" ref="chartAreaRef">
      <el-card class="chart-card" shadow="hover">
        <template #header>
          <div class="chart-card__header">
            <div class="chart-title">
              <h3>动态统计图表</h3>
              <p>图表在可见时才会渲染，从源头控制内存占用，并支持交互切换视角。</p>
            </div>
            <el-tabs v-model="activeChartTab" class="chart-tabs" stretch>
              <el-tab-pane label="进度分布" name="progress" />
              <el-tab-pane label="状态结构" name="status" />
              <el-tab-pane label="趋势对比" name="trend" />
              <el-tab-pane label="团队效率" name="team" />
            </el-tabs>
          </div>
        </template>

        <div class="chart-switcher">
          <div v-show="activeChartTab === 'progress'" ref="progressChartEl" class="chart-instance" />
          <div v-show="activeChartTab === 'status'" ref="statusChartEl" class="chart-instance" />

          <div v-show="activeChartTab === 'trend'" class="chart-instance chart-instance--trend">
            <div class="chart-instance__controls">
              <el-checkbox v-model="trendSeriesVisibility.created">新建项目</el-checkbox>
              <el-checkbox v-model="trendSeriesVisibility.completed">完成项目</el-checkbox>
            </div>
            <div ref="trendChartEl" class="chart-instance__canvas" />
          </div>

          <div v-show="activeChartTab === 'team'" class="chart-instance chart-instance--team">
            <div ref="teamChartEl" class="chart-instance__canvas" />
            <aside v-if="teamHighlights.length" class="team-highlight">
              <div class="team-highlight__leader">
                <span class="leader-label">效率冠军</span>
                <strong class="leader-name">{{ teamHighlights[0].name }}</strong>
                <small class="leader-meta">
                  完成 {{ teamHighlights[0].completed_count }} / {{ teamHighlights[0].total_count }}
                </small>
              </div>
              <ul class="team-highlight__list">
                <li v-for="member in teamHighlights.slice(1, 5)" :key="member.user_id">
                  <span>{{ member.name }}</span>
                  <span>{{ member.completed_count }} / {{ member.total_count }}</span>
                </li>
              </ul>
            </aside>
          </div>
        </div>
      </el-card>
    </section>

    <section class="projects-section">
      <el-card shadow="hover">
        <template #header>
          <div class="projects-header">
            <div>
              <h3>项目速览</h3>
              <p>重点关注近期活跃项目，点击即可查看详情或进一步管理。</p>
            </div>
            <el-button text size="small" @click="router.push('/projects')">
              查看全部
              <el-icon><ArrowRight /></el-icon>
            </el-button>
          </div>
        </template>

        <div v-if="projectListLoading" class="project-skeleton">
          <el-skeleton animated :count="2" />
        </div>
        <el-empty v-else-if="!highlightProjects.length" description="暂无项目数据" />
        <div v-else class="project-grid">
          <el-card
            v-for="project in highlightProjects"
            :key="project.id"
            class="project-item"
            shadow="hover"
            @click="router.push(`/projects/${project.id}`)"
          >
            <div class="project-item__header">
              <h4>{{ project.name }}</h4>
              <el-tag size="small" :type="getPriorityTagType(project.priority)">
                {{ getPriorityLabel(project.priority) }}
              </el-tag>
            </div>
            <p class="project-item__desc">{{ project.description || '这个项目还没有描述。' }}</p>
            <div class="project-item__meta">
              <el-tag
                size="small"
                :style="{
                  backgroundColor: getStatusMeta(project.status).color,
                  borderColor: 'transparent',
                  color: '#fff'
                }"
              >
                {{ getStatusMeta(project.status).label }}
              </el-tag>
              <span class="project-item__progress">
                进度 {{ Math.round(project.progress ?? 0) }}%
              </span>
            </div>
            <div class="project-item__footer">
              <span>创建人：{{ getCreatorName(project) }}</span>
              <span>{{ formatDate(project.start_date) }} - {{ formatDate(project.end_date) }}</span>
            </div>
          </el-card>
        </div>
      </el-card>
    </section>
  </div>
</template>

<script setup lang="ts">
import {
  computed,
  reactive,
  ref,
  shallowRef,
  onMounted,
  onBeforeUnmount,
  watch,
  nextTick
} from 'vue'

// Props
interface Props {
  hideHeader?: boolean
}
const props = withDefaults(defineProps<Props>(), {
  hideHeader: false
})
import dayjs from 'dayjs'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import {
  Refresh,
  TrendCharts,
  FolderOpened,
  Histogram,
  CircleCheck,
  Warning,
  Search,
  ArrowRight
} from '@element-plus/icons-vue'
import { useDebounceFn, useIntersectionObserver, useEventListener } from '@vueuse/core'
import * as echarts from 'echarts'
import { getProjectDashboardStats, getProjectList, type Project } from '@/api/project'
import { useProjectStatsStore } from '@/stores/projectStats'
import type { ProjectStats as ProjectStatsSnapshot } from '@/stores/projectStats'
import { useStateStore } from '@/stores/state'
import { ModuleType } from '@/types/core'

type ChartKey = 'progress' | 'status' | 'trend' | 'team'
type QuickRangeValue = '30d' | '90d' | '180d' | '365d' | 'custom'

interface DashboardPayload {
  progress_distribution: Array<{ name: string; value: number }>
  status_distribution: Array<{ name: string; value: number; code: string }>
  trend_data: {
    labels: string[]
    created: number[]
    completed: number[]
  }
  team_efficiency: Array<{
    user_id: string
    name: string
    completed_count: number
    total_count: number
  }>
}

interface SummaryCard {
  key: string
  title: string
  subtitle: string
  displayValue: string
  trend: number
  tint: string
  color: string
  icon: any
}

const chartKeys: ChartKey[] = ['progress', 'status', 'trend', 'team']

const router = useRouter()
const projectStatsStore = useProjectStatsStore()
const stateStore = useStateStore()

const loading = ref(false)
const projectListLoading = ref(false)

const filters = reactive<{
  period: 'week' | 'month' | 'quarter'
  dateRange: string[]
}>({
  period: 'month',
  dateRange: []
})

const quickRangeOptions = [
  { value: '30d' as QuickRangeValue, label: '近30天', period: 'week', days: 30 },
  { value: '90d' as QuickRangeValue, label: '近90天', period: 'month', days: 90 },
  { value: '180d' as QuickRangeValue, label: '近180天', period: 'month', days: 180 },
  { value: '365d' as QuickRangeValue, label: '近一年', period: 'quarter', days: 365 },
  { value: 'custom' as QuickRangeValue, label: '自定义', period: 'month', days: 0 }
] as const

const quickRange = ref<QuickRangeValue>('90d')

const selectedProjectId = ref<string>('')
const projectOptions = ref<Project[]>([])

// 空仪表盘数据结构
const emptyDashboardData: DashboardPayload = {
  progress_distribution: [],
  status_distribution: [],
  trend_data: {
    labels: [],
    created: [],
    completed: []
  },
  team_efficiency: []
}

const dashboardData = ref<DashboardPayload>({ ...emptyDashboardData })

// 重置仪表盘数据为空数据
const resetDashboardData = () => {
  dashboardData.value = { ...emptyDashboardData }
}

const projects = ref<Project[]>([])
const highlightProjects = computed(() => projects.value.slice(0, 8))

const statsDelta = reactive({
  total: 0,
  active: 0,
  completed: 0,
  overdue: 0
})
const hasStatsInitialized = ref(false)
const previousStatsSnapshot = ref<ProjectStatsSnapshot | null>(null)

const formatNumber = (value: number): string => {
  const safeValue = Number.isFinite(value) ? value : 0
  if (safeValue >= 10000) return `${(safeValue / 10000).toFixed(1)}w`
  if (safeValue >= 1000) return `${(safeValue / 1000).toFixed(1)}k`
  return safeValue.toString()
}

const summaryCards = computed<SummaryCard[]>(() => [
  {
    key: 'total',
    title: '项目总数',
    subtitle: '全部项目数量',
    displayValue: formatNumber(projectStatsStore.stats.total_projects ?? 0),
    trend: statsDelta.total,
    tint: 'rgba(59, 130, 246, 0.12)',
    color: '#3b82f6',
    icon: FolderOpened
  },
  {
    key: 'active',
    title: '进行中项目',
    subtitle: '当前活跃项目',
    displayValue: formatNumber(projectStatsStore.stats.active_projects ?? 0),
    trend: statsDelta.active,
    tint: 'rgba(16, 185, 129, 0.12)',
    color: '#10b981',
    icon: Histogram
  },
  {
    key: 'completed',
    title: '已完成项目',
    subtitle: '阶段性成果',
    displayValue: formatNumber(projectStatsStore.stats.completed_projects ?? 0),
    trend: statsDelta.completed,
    tint: 'rgba(168, 85, 247, 0.12)',
    color: '#a855f7',
    icon: CircleCheck
  },
  {
    key: 'overdue',
    title: '逾期项目',
    subtitle: '需要关注的项目',
    displayValue: formatNumber(projectStatsStore.stats.overdue_projects ?? 0),
    trend: statsDelta.overdue,
    tint: 'rgba(249, 115, 22, 0.12)',
    color: '#f97316',
    icon: Warning
  }
])

const statusMetadata = computed(() => {
  const states = stateStore.getStatesByModule(ModuleType.PROJECT)
  const result: Record<string, { label: string; color: string }> = {}
  states.forEach((state) => {
    result[state.code] = {
      label: state.name,
      color: state.color || '#6b7280'
    }
  })
  return result
})

const getStatusMeta = (status: string) =>
  statusMetadata.value[status] ?? { label: status || '未知', color: '#6b7280' }

const PRIORITY_MAP: Record<
  string,
  {
    label: string
    type: 'primary' | 'success' | 'warning' | 'danger' | 'info'
  }
> = {
  low: { label: '低', type: 'success' },
  medium: { label: '中', type: 'primary' },
  high: { label: '高', type: 'warning' },
  critical: { label: '紧急', type: 'danger' }
}

const getPriorityLabel = (priority?: string) => PRIORITY_MAP[priority ?? '']?.label ?? '普通'
const getPriorityTagType = (priority?: string) => PRIORITY_MAP[priority ?? '']?.type ?? 'info'

const formatDate = (date?: string) => {
  if (!date) return '—'
  return dayjs(date).format('YYYY/MM/DD')
}

const getCreatorName = (project: Project) => {
  // 优先使用 created_by_name，如果没有则显示"未知"
  if (project.created_by_name && project.created_by_name.trim()) {
    return project.created_by_name
  }
  return '未知'
}

const teamHighlights = computed(() =>
  dashboardData.value.team_efficiency
    .slice()
    .sort((a, b) => b.completed_count - a.completed_count)
    .slice(0, 6)
)

const progressChartEl = ref<HTMLDivElement | null>(null)
const statusChartEl = ref<HTMLDivElement | null>(null)
const trendChartEl = ref<HTMLDivElement | null>(null)
const teamChartEl = ref<HTMLDivElement | null>(null)

const chartRefs: Record<ChartKey, typeof progressChartEl> = {
  progress: progressChartEl,
  status: statusChartEl,
  trend: trendChartEl,
  team: teamChartEl
}

const chartInstances: Record<ChartKey, ReturnType<typeof shallowRef<echarts.ECharts | null>>> = {
  progress: shallowRef<echarts.ECharts | null>(null),
  status: shallowRef<echarts.ECharts | null>(null),
  trend: shallowRef<echarts.ECharts | null>(null),
  team: shallowRef<echarts.ECharts | null>(null)
}

const activeChartTab = ref<ChartKey>('progress')
const chartAreaRef = ref<HTMLElement | null>(null)
const chartAreaVisible = ref(false)
const trendSeriesVisibility = reactive({
  created: true,
  completed: true
})

const chartPalette = ['#60a5fa', '#38bdf8', '#a855f7', '#f59e0b', '#34d399', '#f97316']

const buildProgressOption = (): echarts.EChartsOption => {
  const data = dashboardData.value.progress_distribution.length
    ? dashboardData.value.progress_distribution
    : [
        { name: '0-25%', value: 0 },
        { name: '26-50%', value: 0 },
        { name: '51-75%', value: 0 },
        { name: '76-100%', value: 0 }
      ]

  const total = data.reduce((sum, item) => sum + (item.value || 0), 0)

  return {
    color: chartPalette,
    tooltip: {
      trigger: 'item'
    },
    legend: {
      bottom: 0,
      icon: 'circle'
    },
    graphic: [
      {
        type: 'text',
        left: 'center',
        top: 'center',
        style: {
          text: total ? `总项目\n${total}` : '暂无数据',
          fill: '#1f2937',
          fontSize: 16,
          fontWeight: 600
        } as any
      }
    ],
    series: [
      {
        name: '进度分布',
        type: 'pie',
        radius: ['50%', '72%'],
        avoidLabelOverlap: true,
        itemStyle: {
          borderRadius: 6,
          borderColor: '#fff',
          borderWidth: 2
        },
        label: {
          show: true,
          formatter: '{b}\n{d}%'
        },
        data
      }
    ]
  }
}

const buildStatusOption = (): echarts.EChartsOption => {
  const data = dashboardData.value.status_distribution.map((item) => ({
    name: getStatusMeta(item.code).label,
    value: item.value
  }))

  return {
    color: chartPalette,
    tooltip: {
      trigger: 'item'
    },
    visualMap: {
      show: false,
      min: 0,
      max: Math.max(...data.map((d) => d.value), 1),
      inRange: {
        colorLightness: [0.35, 0.9]
      }
    },
    series: [
      {
        name: '状态结构',
        type: 'pie',
        radius: ['30%', '70%'],
        roseType: 'radius',
        itemStyle: {
          borderRadius: 8
        },
        label: {
          formatter: '{b}\n{c} ({d}%)'
        },
        data
      }
    ]
  }
}

const buildTrendOption = (): echarts.EChartsOption => {
  const labels = dashboardData.value.trend_data.labels
  const series: echarts.SeriesOption[] = []

  if (trendSeriesVisibility.created) {
    series.push({
      name: '新建项目',
      type: 'line',
      smooth: true,
      symbol: 'circle',
      symbolSize: 6,
      lineStyle: { width: 2 },
      areaStyle: {
        opacity: 0.15
      },
      data: dashboardData.value.trend_data.created
    })
  }

  if (trendSeriesVisibility.completed) {
    series.push({
      name: '完成项目',
      type: 'line',
      smooth: true,
      symbol: 'circle',
      symbolSize: 6,
      lineStyle: { width: 2 },
      areaStyle: {
        opacity: 0.15
      },
      data: dashboardData.value.trend_data.completed
    })
  }

  if (!series.length) {
    series.push({
      name: '暂无数据',
      type: 'line',
      data: new Array(labels.length).fill(0),
      showSymbol: false,
      lineStyle: { opacity: 0 }
    })
  }

  return {
    color: ['#60a5fa', '#34d399'],
    tooltip: {
      trigger: 'axis'
    },
    grid: {
      left: 40,
      right: 20,
      top: 40,
      bottom: 30
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: labels
    },
    yAxis: {
      type: 'value',
      splitLine: {
        lineStyle: {
          type: 'dashed'
        }
      }
    },
    series
  }
}

const buildTeamOption = (): echarts.EChartsOption => {
  const data = dashboardData.value.team_efficiency
    .slice()
    .sort((a, b) => b.completed_count - a.completed_count)
    .slice(0, 10)

  return {
    color: ['#a855f7'],
    grid: {
      left: 120,
      right: 20,
      top: 20,
      bottom: 20
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' }
    },
    xAxis: {
      type: 'value',
      boundaryGap: [0, 0.01]
    },
    yAxis: {
      type: 'category',
      data: data.map((item) => item.name).reverse()
    },
    series: [
      {
        name: '完成项目数',
        type: 'bar',
        data: data.map((item) => item.completed_count).reverse(),
        barWidth: 18,
        itemStyle: {
          borderRadius: [6, 6, 6, 6]
        },
        label: {
          show: true,
          position: 'right'
        }
      }
    ]
  }
}

const getChartOption = (key: ChartKey): echarts.EChartsOption => {
  switch (key) {
    case 'progress':
      return buildProgressOption()
    case 'status':
      return buildStatusOption()
    case 'trend':
      return buildTrendOption()
    case 'team':
      return buildTeamOption()
    default:
      return {}
  }
}

const ensureChart = async (key: ChartKey) => {
  if (!chartAreaVisible.value) return
  await nextTick()
  const el = chartRefs[key].value
  if (!el) {
    console.warn(`图表容器不存在: ${key}`)
    return
  }

  try {
    if (!chartInstances[key].value) {
      chartInstances[key].value = echarts.init(el, undefined, { renderer: 'canvas' })
    }
    const option = getChartOption(key)
    chartInstances[key].value?.setOption(option, true)
  } catch (error) {
    console.error(`初始化图表失败 (${key}):`, error)
  }
}

const disposeChart = (key: ChartKey) => {
  const instance = chartInstances[key].value
  if (instance) {
    instance.dispose()
    chartInstances[key].value = null
  }
}

const updateActiveChart = () => {
  const key = activeChartTab.value
  try {
    if (chartInstances[key].value) {
      const option = getChartOption(key)
      chartInstances[key].value?.setOption(option, true)
    } else {
      ensureChart(key)
    }
  } catch (error) {
    console.error(`更新图表失败 (${key}):`, error)
  }
}

const resizeHandler = useDebounceFn(() => {
  const instance = chartInstances[activeChartTab.value].value
  instance?.resize()
}, 200)

const stopResizeListener = useEventListener(window, 'resize', resizeHandler)

const stopObserver = useIntersectionObserver(
  chartAreaRef,
  ([entry]) => {
    chartAreaVisible.value = entry.isIntersecting
    if (entry.isIntersecting) {
      ensureChart(activeChartTab.value)
    } else {
      disposeChart(activeChartTab.value)
    }
  },
  {
    threshold: 0.25
  }
)

watch(
  () => dashboardData.value,
  () => {
    updateActiveChart()
  },
  { deep: true }
)

watch(
  () => [trendSeriesVisibility.created, trendSeriesVisibility.completed],
  () => {
    if (activeChartTab.value === 'trend') {
      updateActiveChart()
    }
  }
)

watch(activeChartTab, (newKey, oldKey) => {
  disposeChart(oldKey)
  ensureChart(newKey)
})

const applyQuickRange = (value: QuickRangeValue) => {
  const option = quickRangeOptions.find((item) => item.value === value)
  if (!option) return

  if (value === 'custom') {
    filters.dateRange = []
    return
  }

  const end = dayjs()
  const start = end.subtract(option.days - 1, 'day')
  filters.dateRange = [start.format('YYYY-MM-DD'), end.format('YYYY-MM-DD')]
  filters.period = option.period
}

const handleQuickRangeChange = (value: string | number | boolean | undefined) => {
  const rangeValue = value as QuickRangeValue
  if (!rangeValue) return
  quickRange.value = rangeValue
  applyQuickRange(rangeValue)
  if (rangeValue !== 'custom') {
    fetchDashboard(true)
  }
}

const handleDateChange = (range: string[] | null) => {
  filters.dateRange = range ?? []
  quickRange.value = 'custom'
  fetchDashboard(true)
}

const handlePeriodChange = () => {
  quickRange.value = 'custom'
  fetchDashboard(true)
}

const handleProjectChange = () => {
  fetchProjects()
  fetchDashboard(true)
}

const createStatsSnapshot = (stats?: ProjectStatsSnapshot | null): ProjectStatsSnapshot => ({
  total_projects: stats?.total_projects ?? 0,
  active_projects: stats?.active_projects ?? 0,
  completed_projects: stats?.completed_projects ?? 0,
  overdue_projects: stats?.overdue_projects ?? 0,
  planning_projects: stats?.planning_projects ?? 0,
  paused_projects: stats?.paused_projects ?? 0,
  cancelled_projects: stats?.cancelled_projects ?? 0
})

const resetStatsDelta = () => {
  statsDelta.total = 0
  statsDelta.active = 0
  statsDelta.completed = 0
  statsDelta.overdue = 0
}

const fetchStats = async () => {
  try {
    const previous = previousStatsSnapshot.value ?? createStatsSnapshot(projectStatsStore.stats)
    await projectStatsStore.refreshStats()
    const current = createStatsSnapshot(projectStatsStore.stats)

    if (hasStatsInitialized.value) {
      statsDelta.total = current.total_projects - previous.total_projects
      statsDelta.active = current.active_projects - previous.active_projects
      statsDelta.completed = current.completed_projects - previous.completed_projects
      statsDelta.overdue = current.overdue_projects - previous.overdue_projects
    } else {
      resetStatsDelta()
      hasStatsInitialized.value = true
    }

    previousStatsSnapshot.value = current
  } catch (error) {
    console.error('获取项目统计失败:', error)
    ElMessage.error('获取项目统计失败')
  }
}

const fetchDashboard = async (showLoading = true) => {
  if (showLoading) {
    loading.value = true
  }
  
  try {
    const params: Record<string, string> = {
      period: filters.period
    }
    if (filters.dateRange.length === 2) {
      params.start_date = filters.dateRange[0]
      params.end_date = filters.dateRange[1]
    }
    // 如果选择了项目，添加项目ID参数
    if (selectedProjectId.value) {
      params.project_id = selectedProjectId.value
    }

    const response = await getProjectDashboardStats(params)
    
    // 改进错误处理
    if (!response) {
      throw new Error('网络请求失败，请检查网络连接')
    }
    
    if (!response.success) {
      throw new Error(response.message || '获取数据失败')
    }
    
    if (!response.data) {
      throw new Error('服务器返回数据为空')
    }

    // 安全地设置数据，确保所有字段都有默认值
    const data = response.data
    dashboardData.value = {
      progress_distribution: Array.isArray(data.progress_distribution) ? data.progress_distribution : [],
      status_distribution: Array.isArray(data.status_distribution) ? data.status_distribution : [],
      trend_data: {
        labels: Array.isArray(data.trend_data?.labels) ? data.trend_data.labels : [],
        created: Array.isArray(data.trend_data?.created) ? data.trend_data.created : [],
        completed: Array.isArray(data.trend_data?.completed) ? data.trend_data.completed : []
      },
      team_efficiency: Array.isArray(data.team_efficiency) ? data.team_efficiency : []
    }

    // 确保趋势数据的长度一致
    const maxLength = Math.max(
      dashboardData.value.trend_data.labels.length,
      dashboardData.value.trend_data.created.length,
      dashboardData.value.trend_data.completed.length
    )
    
    if (dashboardData.value.trend_data.labels.length < maxLength) {
      dashboardData.value.trend_data.labels = Array(maxLength).fill('')
    }
    if (dashboardData.value.trend_data.created.length < maxLength) {
      dashboardData.value.trend_data.created = [
        ...dashboardData.value.trend_data.created,
        ...Array(maxLength - dashboardData.value.trend_data.created.length).fill(0)
      ]
    }
    if (dashboardData.value.trend_data.completed.length < maxLength) {
      dashboardData.value.trend_data.completed = [
        ...dashboardData.value.trend_data.completed,
        ...Array(maxLength - dashboardData.value.trend_data.completed.length).fill(0)
      ]
    }

    // 延迟更新图表，确保DOM已更新
    await nextTick()
    updateActiveChart()
  } catch (error: any) {
    console.error('获取仪表盘数据失败:', error)
    ElMessage.error(`获取仪表盘数据失败：${error?.message || '未知错误'}`)
    // 重置为空数据
    resetDashboardData()
  } finally {
    if (showLoading) {
      loading.value = false
    }
  }
}

// 获取所有项目列表（用于下拉选项）
const fetchProjectOptions = async () => {
  try {
    const response = await getProjectList({
      page: 1,
      size: 1000, // 获取足够多的项目用于下拉选项
      search: '',
      status: '',
      is_archived: false
    })
    projectOptions.value = response.items ?? []
  } catch (error: any) {
    console.error('获取项目选项失败:', error)
  }
}

const fetchProjects = async () => {
  projectListLoading.value = true
  try {
    const params: any = {
      page: 1,
      size: 12,
      status: '',
      is_archived: false  // 仪表盘只显示未归档的项目
    }
    
    // 如果选择了项目，使用项目ID筛选；否则使用搜索关键词
    if (selectedProjectId.value) {
      // 注意：这里假设API支持通过项目ID筛选，如果不支持，可能需要调整
      // 或者可以通过项目名称来筛选
      const selectedProject = projectOptions.value.find(p => p.id === selectedProjectId.value)
      if (selectedProject) {
        params.search = selectedProject.name
      }
    }
    
    const response = await getProjectList(params)
    projects.value = response.items ?? []
  } catch (error: any) {
    console.error('获取项目列表失败:', error)
    ElMessage.error(`获取项目列表失败：${error?.message || '未知错误'}`)
  } finally {
    projectListLoading.value = false
  }
}

const refreshAll = async () => {
  loading.value = true
  try {
    // 并行加载所有数据，提高性能
    await Promise.allSettled([
      fetchStats(),
      fetchDashboard(false), // 不显示单独的loading
      fetchProjectOptions(), // 获取项目选项
      fetchProjects()
    ])
  } catch (error: any) {
    console.error('刷新数据失败:', error)
    ElMessage.error('刷新数据失败，请稍后重试')
  } finally {
    loading.value = false
  }
}

onMounted(async () => {
  await stateStore.fetchStates({ module_type: ModuleType.PROJECT })
  applyQuickRange(quickRange.value)
  await refreshAll()
})

onBeforeUnmount(() => {
  chartKeys.forEach(disposeChart)
  stopObserver?.stop()
  stopResizeListener?.()
})
</script>

<style scoped>
.dashboard-wrapper {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 20px;
  min-height: 100%;
  background: #f5f8ff;
}

.dashboard-filters-bar {
  margin-bottom: 24px;
  padding: 16px 20px;
  background: #ffffff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.filters-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.dashboard-header {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 16px;
  padding: 20px;
  border-radius: 14px;
  background: linear-gradient(135deg, rgba(59, 130, 246, 0.08), rgba(14, 165, 233, 0.08));
  border: 1px solid rgba(59, 130, 246, 0.12);
}

.header-info {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.title {
  margin: 0;
  font-size: 24px;
  font-weight: 600;
  color: #1f2937;
}

.subtitle {
  margin: 0;
  font-size: 14px;
  color: #6b7280;
}

.header-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}

.period-select {
  width: 120px;
}

.range-group :deep(.el-radio-button__inner) {
  padding: 6px 14px;
}

.date-picker {
  width: 250px;
}

.search-select {
  width: 250px;
}

.overview-section {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.stat-card {
  display: flex;
  gap: 14px;
  align-items: center;
  border-radius: 14px;
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.stat-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 28px rgba(15, 23, 42, 0.12);
}

.stat-card__icon {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 12px;
}

.stat-card__content {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.stat-card__label {
  font-size: 14px;
  color: #6b7280;
}

.stat-card__value {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 28px;
  font-weight: 600;
  color: #1f2937;
}

.stat-card__trend {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  padding: 2px 6px;
  border-radius: 999px;
  background: rgba(16, 185, 129, 0.1);
  color: #059669;
}

.stat-card__trend.is-down {
  background: rgba(239, 68, 68, 0.1);
  color: #dc2626;
}

.stat-card__meta {
  margin: 0;
  font-size: 12px;
  color: #9ca3af;
}

.chart-section .chart-card {
  border-radius: 14px;
  overflow: hidden;
}

.chart-card__header {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.chart-title h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #1f2937;
}

.chart-title p {
  margin: 0;
  font-size: 13px;
  color: #6b7280;
}

.chart-switcher {
  position: relative;
  min-height: 360px;
}

.chart-instance {
  width: 100%;
  height: 360px;
}

.chart-instance--trend {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.chart-instance__controls {
  display: flex;
  gap: 16px;
  justify-content: flex-end;
  padding: 4px 0;
}

.chart-instance__canvas {
  flex: 1;
  width: 100%;
  height: 320px;
}

.chart-instance--team {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 220px;
  gap: 20px;
  align-items: stretch;
}

.team-highlight {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px;
  border-radius: 12px;
  background: linear-gradient(180deg, rgba(59, 130, 246, 0.12), rgba(59, 130, 246, 0.05));
}

.team-highlight__leader {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.leader-label {
  font-size: 12px;
  color: #3b82f6;
}

.leader-name {
  font-size: 18px;
  color: #1f2937;
}

.leader-meta {
  font-size: 12px;
  color: #6b7280;
}

.team-highlight__list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.team-highlight__list li {
  display: flex;
  justify-content: space-between;
  font-size: 13px;
  color: #4b5563;
}

.projects-section .el-card {
  border-radius: 14px;
}

.projects-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}

.projects-header h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #1f2937;
}

.projects-header p {
  margin: 0;
  font-size: 13px;
  color: #6b7280;
}

.project-skeleton {
  padding: 12px 0;
}

.project-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 16px;
}

.project-item {
  cursor: pointer;
  border-radius: 12px;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.project-item:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 28px rgba(15, 23, 42, 0.12);
}

.project-item__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.project-item__header h4 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #1f2937;
}

.project-item__desc {
  margin: 0 0 12px;
  font-size: 13px;
  line-height: 1.5;
  color: #6b7280;
  min-height: 40px;
}

.project-item__meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  font-size: 12px;
  color: #6b7280;
}

.project-item__progress {
  font-weight: 500;
  color: #3b82f6;
}

.project-item__footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  color: #9ca3af;
}

.trend-fade-enter-active,
.trend-fade-leave-active {
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.trend-fade-enter-from,
.trend-fade-leave-to {
  opacity: 0;
  transform: translateY(-4px);
}

@media (max-width: 1200px) {
  .chart-instance--team {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 992px) {
  .dashboard-header {
    flex-direction: column;
  }

  .header-actions {
    width: 100%;
  }

  .chart-instance {
    height: 320px;
  }
}

@media (max-width: 768px) {
  .dashboard-wrapper {
    padding: 16px;
  }

  .chart-instance__canvas {
    height: 260px;
  }

  .project-grid {
    grid-template-columns: 1fr;
  }
}
</style>

